using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Text;
using Magiq.Support;

namespace Magiq.Sql {
  public class TableVariableDependentUpdateStrategy : IDependentTablesUpdateStrategy {
    #region IDependentTablesUpdateStrategy Members

    public int Execute<T>(MassUpdate<T> massUpdate, IEnumerable<TableUpdate<T>> tableUpdates) where T : class {
      var dataContext = massUpdate.DataContext;
      var tableVars = new List<string>();
      var columns = new List<string>();
      var values = new List<string>();
      //var q = new DeleteExecutor(massUpdate.)
      var assignmentBuilder = new QueryColumnAssignmentBuilder(dataContext);
      var query = new DeleteExecutor(dataContext, massUpdate.Update.Where);

      foreach (var tableUpdate in tableUpdates) {
        var samplePropertySet = tableUpdate.PropertySets.First();
        var tableType = samplePropertySet.DeclaringType;
        var table = dataContext.Mapping.GetMetaType(tableType);

        foreach (var pk in table.DataMembers.Where(x => x.IsPrimaryKey)) {
          var column = Encode(table.Table.TableName) + "_" + Encode(pk.Name);
          tableVars.Add(column + " " + pk.SqlType());
          columns.Add(column);

          //obtengo el valor q iria para esta columna
          var parameter = Expression.Parameter(typeof (T), "x");
          var pi = (PropertyInfo) pk.Member;
          var getPk = Expression.Property(parameter, pi);
          var body = pi.PropertyType.IsValueType
                       ? (Expression) Expression.Convert(getPk, typeof (object))
                       : getPk;
          var exp = Expression.Lambda<Func<T, object>>(body, parameter);

          var command = dataContext.GetCommand(tableUpdate.Where.Select(exp));
          var sqlValue = command.CommandText.From("SELECT").Until("AS").Until("FROM").Trim();
          values.Add(sqlValue);
        }
      }

      var sqlBuilder = new StringBuilder()
        .Append("declare @table TABLE (")
        .Append(tableVars.Join(","))
        .Append(")")
        .Append("INSERT INTO @table( ")
        .Append(columns.Join(","))
        .Append(") SELECT ")
        .Append(values.Join(","))
        .Append(" FROM ")
        .Append(query.BaseWhereClause);

      //insert into @table( columnas q tengo ) select ......... from el where.
      //cada columna la hago
      return 0;
    }

    #endregion

    private static string Encode(string dbMember) {
      return dbMember.Replace("_", "__");
    }
  }
}